package com.xbongbong.saas.factory.publicrule;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.service.AbstractPublicSeniorRuleService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.enums.RelTypeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.PublicGroupSeniorEntity;
import com.xbongbong.saas.domain.entity.RuleSeniorEntity;
import com.xbongbong.saas.domain.entity.TransferBackRuleSeniorEntity;
import com.xbongbong.saas.enums.ClueSeniorBackChildEnum;
import com.xbongbong.saas.enums.CustomerSeniorBackChildEnum;
import com.xbongbong.saas.enums.SeniorFixedGroupEnum;
import com.xbongbong.saas.enums.SeniorRuleValueEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.help.PublicSeniorRuleHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 公海高级模式 - 转移规则筛选类
 * @author : yanglei
 * @date 创建时间：2022/5/11 下午6:40:08
 * @version
 */
@Component
public class CheckSeniorPublicTransferRule extends AbstractPublicSeniorRuleService  {

	private static final Logger LOG = LoggerFactory.getLogger(CheckSeniorPublicTransferRule.class);

	@Resource
	private PublicSeniorRuleHelp publicSeniorRuleHelp;

	/**
	 * 获取每个用户主负责的客户需要转移公海池的客户列表
	 * @param userEntity 用户
	 * @param rule 规则
	 * @param idIn 用户的客户id列表（不一定是所有的客户）
	 * @param advanceTime 提醒时间
	 * @param explainMap 当前表单开启的字段
	 * @param labelIds 当前表单开启的标签id
	 * @param openGroupIdList 当前表单开启的分组id
	 * @param deleteGroupIdList 当前删除的分组id
	 * @param noGroupId 当前表单无分组id
	 * @param allGroupList 当前表单的全部分组
	 * @return
	 * @throws XbbException
	 */
	@Override
	public List<RuleSeniorEntity> getSeniorBackCustomerList(UserEntity userEntity, TransferBackRuleSeniorEntity rule, List<Long> idIn, Integer advanceTime, Long menuId, Map<String, Integer> explainMap,List<Long> labelIds,List<Long> openGroupIdList, List<Long> deleteGroupIdList,Long noGroupId,List<PublicGroupSeniorEntity> allGroupList) throws XbbException {
		List<RuleSeniorEntity> retList = new ArrayList<>();
		if (Objects.isNull(rule)){
			return retList;
		}
		String corpid = rule.getCorpid();
		Long formId = rule.getFormId();

		LOG.warn("表单模板id：" + formId + ", 当前模板启用的分组数量：" + openGroupIdList.size());

		if (CollectionsUtil.isEmpty(openGroupIdList)){
			return retList;
		}

		if (Objects.isNull(advanceTime)){
			advanceTime = 0;
		}
		JSONArray jsonDataArray = rule.getJsonData();
		//若规则设置后字段被删除或未启用，则展示attr且此字段规则不再有效
		removeNoOpenOrDelete4FilterScreen(jsonDataArray,explainMap,labelIds);
		/**
		 *  1、获取不转移筛选条件的客户
		 */
		List<ConditionsEntityExt> noBackConditionList = JSONArray.parseArray(jsonDataArray.toJSONString(), ConditionsEntityExt.class);
		List<RuleSeniorEntity> noBackCustomerList = new ArrayList<>();
		if (CollectionsUtil.isNotEmpty(noBackConditionList)){
			//地址筛选条件特殊处理
			publicSeniorRuleHelp.addressSearchShouldCondition(noBackConditionList);
			noBackCustomerList = getCustomerListByEs(idIn,noBackConditionList,null, corpid, formId,RelTypeEnum.OR.getAlias(),BasicConstant.ONE,null);
		}

		LOG.warn("表单模板id：" + formId + ",不转移的客户数量：" + noBackCustomerList.size());


		/**
		 *  2、获取符合退回筛选条件的客户
		 */
		JSONArray ruleValueArray = rule.getRuleValue();
		if (CollectionsUtil.isEmpty(ruleValueArray)){
			return retList;
		}
		//最外层退回规则集合
		for (Object ruleValueObj : ruleValueArray){
			if (CollectionsUtil.isEmpty(idIn)){
				break;
			}
			List<Long> noBackIds = new ArrayList<>();
			//每个优先级转移的线索列表
			List<RuleSeniorEntity> ruleValueTransferList = new ArrayList<>();
			JSONObject ruleValue = (JSONObject) ruleValueObj;
			//如果目标公海分组未启用获已删除，该转移规则失效
			JSONObject objectGroup = FastJsonHelper.getJsonObjectOrDefault(ruleValue, SeniorRuleValueEnum.OBJECTIVE_GROUP.getAlias(), new JSONObject());
			Long objectGroupId = objectGroup != null ? objectGroup.getLong("value") : -10L;
			if (!openGroupIdList.contains(objectGroupId) && !SeniorFixedGroupEnum.isNowPreGroup(objectGroupId)){
				continue;
			}
			String ruleName = ruleValue.getString("name");
			//适用范围分组id
			JSONArray applyScopeArray = FastJsonHelper.getJsonArrayOrDefault(ruleValue, SeniorRuleValueEnum.APPLY_SCOPE.getAlias(), new JSONArray());
			//筛选条件
			JSONObject filterScreen = FastJsonHelper.getJsonObjectOrDefault(ruleValue, SeniorRuleValueEnum.FILTER_SCREEN.getAlias(), new JSONObject());
			JSONArray filterRule = new JSONArray();
			if (Objects.nonNull(filterScreen)){
				filterRule = Objects.equals(filterScreen.getInteger("filterType"), BasicConstant.ONE) ? new JSONArray() : filterScreen.getJSONArray("filterRule");
			}
			//若规则设置后字段被删除或未启用，则展示attr且此字段规则不再有效
			removeNoOpenOrDelete4FilterScreen(filterRule,explainMap,labelIds);
			//封装其他筛选条件
			List<ConditionsEntityExt> backConditionList = JSONArray.parseArray(filterRule.toJSONString(), ConditionsEntityExt.class);
			//适用范围条件封装,需要shouldCondition
			List<List<ConditionsEntityExt>> applyScoreShouldCondition = packageApplyScoreCondition(applyScopeArray, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), openGroupIdList,deleteGroupIdList,noGroupId);
			//地址筛选条件特殊处理
			publicSeniorRuleHelp.addressSearchShouldCondition(backConditionList);
			List<RuleSeniorEntity> backCustomerList = getCustomerListByEs(idIn,backConditionList, applyScoreShouldCondition,corpid, formId,RelTypeEnum.AND.getAlias(),BasicConstant.ONE,null);

			LOG.warn("优先级为：" + ruleValue.getInteger("sort") + ",表单模板id：" + formId + ",转移规则名称："+ ruleName + ",转移筛选条件查询的客户数：" + backCustomerList.size());

			noBackCustomerList.forEach(item -> noBackIds.add(item.getId()));

			/**
			 * 3、移除不转移的客户
			 */
			backCustomerList = backCustomerList.stream().filter(item -> !noBackIds.contains(item.getId())).collect(Collectors.toList());

			if (CollectionsUtil.isEmpty(backCustomerList)){
				continue;
			}

			/**
			 * 4、触发条件筛选客户  triggerScreen 集合
			 */
			JSONObject triggerScreenJson = FastJsonHelper.getJsonObjectOrDefault(ruleValue, SeniorRuleValueEnum.TRIGGER_SCREEN.getAlias(), new JSONObject());

			//转移规则这里只支持定时退回，不支持当日退回，只做定时退回筛选，并且没有特殊员工和所有员工的概念
			JSONArray triggerRuleArray = FastJsonHelper.getJsonArrayOrDefault(triggerScreenJson, "rule", new JSONArray());
			if(CollectionsUtil.isNotEmpty(triggerRuleArray)){
				triggerRuleFilter(triggerRuleArray,backCustomerList,ruleValueTransferList,advanceTime,XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),rule.getType(),ruleName);
			}

			LOG.warn("优先级为：" + ruleValue.getInteger("sort") +  ",表单模板id：" + formId + ",转移规则名称："+ ruleName + ",最终需要转移的客户数：" + ruleValueTransferList.size());

			if (CollectionsUtil.isEmpty(ruleValueTransferList)){
				continue;
			}
			/**
			 * 5、获取目标公海id,如果客户所绑定公海分组未启用，或者已删除，该客户不退回公海池
			 */
			analysisObjectGroup(ruleValueTransferList,ruleValue,allGroupList,XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),objectGroupId);

			List<Long> retIds = ruleValueTransferList.stream().map(RuleSeniorEntity::getId).collect(Collectors.toList());
			//去除第一条规则已经符合条件的客户,后面相同客户符合的规则就筛选不到
			idIn.removeIf(v -> retIds.contains(v));

			retList.addAll(ruleValueTransferList);
		}
		return retList;
	}


	@Override
	public List<RuleSeniorEntity> getSeniorBackClueList(UserEntity userEntity, TransferBackRuleSeniorEntity rule, List<Long> idIn, Integer advanceTime,Map<String, Integer> explainMap,List<Long> labelIds,List<Long> openGroupIdList, List<Long> deleteGroupIdList,Long noGroupId,List<PublicGroupSeniorEntity> allGroupList) throws XbbException {
		List<RuleSeniorEntity> retList = new ArrayList<>();
		if (Objects.isNull(rule)){
			return retList;
		}
		String corpid = rule.getCorpid();
		Long formId = rule.getFormId();
		if (Objects.isNull(advanceTime)){
			advanceTime = 0;
		}
		LOG.warn("表单模板id：" + formId + ", 当前模板启用的分组数量：" + openGroupIdList.size());

		if (CollectionsUtil.isEmpty(openGroupIdList)){
			return retList;
		}

		JSONArray jsonDataArray = rule.getJsonData();
		//若规则设置后字段被删除或未启用，则展示attr且此字段规则不再有效
		removeNoOpenOrDelete4FilterScreen(jsonDataArray,explainMap,labelIds);

		/**
		 *  1、获取不退回筛选条件的线索
		 */
		List<ConditionsEntityExt> noBackConditionList = JSONArray.parseArray(jsonDataArray.toJSONString(), ConditionsEntityExt.class);
		List<RuleSeniorEntity> noBackClueList = new ArrayList<>();
		if (CollectionsUtil.isNotEmpty(noBackConditionList)){
			//地址筛选条件特殊处理
			publicSeniorRuleHelp.addressSearchShouldCondition(noBackConditionList);
			noBackClueList = getClueListByEs(idIn,noBackConditionList,null, corpid, formId,RelTypeEnum.OR.getAlias(),BasicConstant.ONE);
		}

		LOG.warn("表单模板id：" + formId + ",不转移的线索数量：" + noBackClueList.size());

		/**
		 *  2、获取符合退回筛选条件的线索
		 */
		JSONArray ruleValueArray = rule.getRuleValue();
		if (CollectionsUtil.isEmpty(ruleValueArray)){
			return retList;
		}
		//最外层退回规则集合
		for (Object ruleValueObj : ruleValueArray){
			if (CollectionsUtil.isEmpty(idIn)){
				break;
			}
			List<Long> noBackIds = new ArrayList<>();
			//每个优先级转移的线索列表
			List<RuleSeniorEntity> ruleValueTransferList = new ArrayList<>();
			JSONObject ruleValue = (JSONObject) ruleValueObj;
			//如果目标公海分组未启用获已删除，该转移规则失效
			JSONObject objectGroup = FastJsonHelper.getJsonObjectOrDefault(ruleValue, SeniorRuleValueEnum.OBJECTIVE_GROUP.getAlias(), new JSONObject());
			Long objectGroupId = objectGroup != null ? objectGroup.getLong("value") : -10L;
			if (!openGroupIdList.contains(objectGroupId) && !SeniorFixedGroupEnum.isNowPreGroup(objectGroupId)){
				continue;
			}
			String ruleName = ruleValue.getString("name");
			//适用范围分组id集合
			JSONArray applyScopeArray = FastJsonHelper.getJsonArrayOrDefault(ruleValue, SeniorRuleValueEnum.APPLY_SCOPE.getAlias(), new JSONArray());
			//筛选条件
			JSONObject filterScreen = FastJsonHelper.getJsonObjectOrDefault(ruleValue, SeniorRuleValueEnum.FILTER_SCREEN.getAlias(), new JSONObject());
			JSONArray filterRule = new JSONArray();
			if (Objects.nonNull(filterScreen)){
				filterRule = Objects.equals(filterScreen.getInteger("filterType"), BasicConstant.ONE) ? new JSONArray() : filterScreen.getJSONArray("filterRule");
			}
			//若规则设置后字段被删除或未启用，则展示attr且此字段规则不再有效
			removeNoOpenOrDelete4FilterScreen(jsonDataArray,explainMap,labelIds);
			//封装其他筛选条件
			List<ConditionsEntityExt> backConditionList = JSONArray.parseArray(filterRule.toJSONString(), ConditionsEntityExt.class);
			//适用范围条件封装,需要shouldCondition
			List<List<ConditionsEntityExt>> applyScoreShouldCondition = packageApplyScoreCondition(applyScopeArray, XbbRefTypeEnum.CLUE.getCode(), openGroupIdList,deleteGroupIdList,noGroupId);
			//地址筛选条件特殊处理
			publicSeniorRuleHelp.addressSearchShouldCondition(backConditionList);
			List<RuleSeniorEntity> backClueList = getClueListByEs(idIn,backConditionList,applyScoreShouldCondition, corpid, formId,RelTypeEnum.AND.getAlias(),BasicConstant.ONE);

			LOG.warn("优先级为：" + ruleValue.getInteger("sort") + ",表单模板id：" + formId + ",转移规则名称："+ ruleName + ",转移筛选条件查询的线索数：" + backClueList.size());

			noBackClueList.forEach(item -> noBackIds.add(item.getId()));

			/**
			 * 3、移除不退回的线索
			 */
			backClueList = backClueList.stream().filter(item -> !noBackIds.contains(item.getId())).collect(Collectors.toList());

			if (CollectionsUtil.isEmpty(backClueList)){
				continue;
			}

			/**
			 * 4、触发条件筛选客户  triggerScreen 集合
			 */
			JSONObject triggerScreenJson = FastJsonHelper.getJsonObjectOrDefault(ruleValue, SeniorRuleValueEnum.TRIGGER_SCREEN.getAlias(), new JSONObject());
			//转移规则这里只支持定时退回，不支持当日退回，只做定时退回筛选，并且没有特殊员工和所有员工的概念
			JSONArray triggerRuleArray = FastJsonHelper.getJsonArrayOrDefault(triggerScreenJson, "rule", new JSONArray());
			if(CollectionsUtil.isNotEmpty(triggerRuleArray)){
				triggerRuleFilter(triggerRuleArray,backClueList,ruleValueTransferList,advanceTime,XbbRefTypeEnum.CLUE.getCode(),rule.getType(),ruleName);
			}

			LOG.warn("优先级为：" + ruleValue.getInteger("sort") +  ",表单模板id：" + formId + ",转移规则名称："+ ruleName + ",最终需要转移的线索数：" + ruleValueTransferList.size());

			if (CollectionsUtil.isEmpty(ruleValueTransferList)){
				continue;
			}
			/**
			 * 5、获取目标公海id,如果客户所绑定公海分组未启用，或者已删除，该客户不退回公海池
			 */
			analysisObjectGroup(ruleValueTransferList,ruleValue,allGroupList,XbbRefTypeEnum.CLUE.getCode(),objectGroupId);

			List<Long> retIds = ruleValueTransferList.stream().map(RuleSeniorEntity::getId).collect(Collectors.toList());
			//去除第一条规则已经符合条件的客户,后面相同客户符合的规则就筛选不到
			idIn.removeIf(v -> retIds.contains(v));

			retList.addAll(ruleValueTransferList);
		}
		return retList;
	}


	/**
	 * 客户公海高级模式 - 转移规则  触发条件定时退回的筛选
	 * @param triggerRuleArray 触发条件
	 * @param backCustomerList 筛选条件筛选出来的客户
	 * @param advanceTime 提醒时间
	 * @param businessType 业务类型
	 * @param ruleType 规则类型
	 * @param ruleName 规则名称
	 */
	public void triggerRuleFilter(JSONArray triggerRuleArray, List<RuleSeniorEntity> backCustomerList,List<RuleSeniorEntity> ruleValueTransferList,Integer advanceTime,Integer businessType,Integer ruleType,String ruleName){

		//转移规则中最小的设置天数
		Integer transferDay = getTransferMinDayMap(triggerRuleArray);
		if(transferDay == null){
			return;
		}
		Integer chooseType = CustomerSeniorBackChildEnum.CUSTOMER_NO_GAIN_DISTRIBUTION.getCode();
		if(Objects.equals(businessType,XbbRefTypeEnum.CLUE.getCode())){
			chooseType = ClueSeniorBackChildEnum.CLUE_NO_GAIN_DISTRIBUTION.getCode();
		}
		for (RuleSeniorEntity ruleSenior : backCustomerList){
			long nowTime = DateTimeUtil.getInt();
			ruleSenior.setChooseType(chooseType);
			//获取该客户或者线索的公海退回时间
			Long lastBackTime = ruleSenior.getLastBackTime();
			//原天数
			Integer orDay = transferDay;
			transferDay -= advanceTime;
			transferDay = transferDay < 0 ? 0 : transferDay;
			Long second = transferDay * 86400L;
			//day过大 Long溢出
			if(transferDay > 0 && second < 0L){
				continue;
			}
			if(nowTime - lastBackTime > second){
				setLeftDay(ruleSenior,ruleName,lastBackTime, orDay,ruleType,"");
				ruleValueTransferList.add(ruleSenior);
			}
		}
	}
}